#pragma GCC optimize(2, "Ofast", "inline")
#include <iostream>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <unordered_map>
#include <algorithm>
#define endl '\n'
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
#define int128 __int128_t
using namespace std;

// 已知
int n, m, a, b, w;
vector<vector<pii>> g; // 邻接表表示图，每个元素是 (目标顶点, 权重)
// 未知
int ans = 1 << 30; // 初始化为无穷大
const int MAX_VISITS = 1024; // 2^10，因为权重小于2^10

void input()
{
    cin >> n >> m;
    g.resize(n + 1); // 顶点编号从1开始
    for (int i = 0; i < m; ++i)
    {
        cin >> a >> b >> w;
        g[a].push_back({ b, w }); // 添加有向边
    }
}

void bfs()
{
    // 使用队列，按照异或值排序
    queue<pii> q;
    bool vis[n + 1][1024] = { 0 }; // 记录是否点i异或数值是w是否访问过
    // 初始化
    vis[1][0] = 1; // 从顶点1到顶点1的异或值为0
    q.push({ 1, 0 }); // (异或值, 顶点)
    while (!q.empty())
    {
        auto [v, w] = q.front(); // (顶点, 异或值)
        q.pop();
        for (auto [nv, nw] : g[v]) // 遍历所有邻居
        {
            nw ^= w; // 异或得到新的邻居数值
            if (!vis[nv][nw]) // 只要这个邻居的这个异或数值没访问过
            {
                vis[nv][nw] = 1; // 标记为访问过
                q.push({ nv,nw }); // 加入队列
                if (nv == n) ans = min(ans, nw); // 如果到达终点，更新答案
            }
        }
    }
    if (ans == 1 << 30) ans = -1;
}

signed main()
{
    cin.tie(0)->ios::sync_with_stdio(false);
    input();
    bfs();
    cout << ans;
    return 0;
}